home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * parstxtr.c
- *
- * This module parses textures and atmosphere effects.
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "vector.h"
- #include "povproto.h"
- #include "parse.h"
- #include "parstxtr.h"
- #include "colour.h"
- #include "express.h"
- #include "gif.h"
- #include "halos.h"
- #include "iff.h"
- #include "image.h"
- #include "matrices.h"
- #include "normal.h"
- #include "pigment.h"
- #include "povray.h"
- #include "pgm.h"
- #include "ppm.h"
- #include "targa.h"
- #include "png_pov.h"
- #include "texture.h"
- #include "tokenize.h"
-
-
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
-
- #define ADD_TNORMAL if (Tnormal == NULL) {if ((Default_Texture->Tnormal) != NULL) \
- Tnormal = Copy_Tnormal ((Default_Texture->Tnormal)); else Tnormal = Create_Tnormal ();\
- Texture->Tnormal=Tnormal;};
-
- /*****************************************************************************
- * Local typedefs
- ******************************************************************************/
-
-
-
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
-
- TEXTURE *Default_Texture;
-
-
-
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
-
- static void Parse_Bump_Map PARAMS((TNORMAL *Tnormal));
- static void Parse_Image_Map PARAMS((PIGMENT *Pigment));
- static void Parse_Pattern PARAMS((TPATTERN *New, int TPat_Type));
- static TEXTURE *Parse_Vers1_Texture PARAMS((void));
- static TEXTURE *Parse_Tiles PARAMS((void));
- static TEXTURE *Parse_Material_Map PARAMS((void));
- static void Parse_Texture_Transform PARAMS((TEXTURE *Texture));
- static TURB *Check_Turb PARAMS((WARP **Warps_Ptr));
- static void Parse_Warp PARAMS((WARP **Warp_Ptr));
- static void Check_BH_Parameters PARAMS((BLACK_HOLE *bh));
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- IMAGE *Parse_Image (Legal)
- int Legal;
- {
- IMAGE *Image;
- VECTOR Local_Vector;
- char *Name;
-
- Image = Create_Image ();
-
- Image->Image_Type = Legal;
-
- if (Legal & GRAD_FILE)
- {
- EXPECT
- CASE_VECTOR
- Warn(1.5, "Should use map_type keyword and/or eliminate orientation.");
- Have_Vector = FALSE;
- Parse_Vector_Float (Local_Vector);
- if (Have_Vector)
- Assign_Vector(Image->Gradient,Local_Vector);
- else
- Image->Map_Type = (int)Local_Vector[X];
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- }
-
- EXPECT
- CASE (IFF_TOKEN)
- Image->File_Type = IFF_FILE;
- Name=Parse_String();
- Read_Iff_Image (Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (GIF_TOKEN)
- Image->File_Type = GIF_FILE;
- Name=Parse_String();
- Read_Gif_Image(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (POT_TOKEN)
- Image->File_Type = POT_FILE;
- Name=Parse_String();
- Read_Gif_Image(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (SYS_TOKEN)
- Image->File_Type = SYS_FILE;
- Name=Parse_String();
- READ_SYS_IMAGE(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (TGA_TOKEN)
- Image->File_Type = TGA_FILE;
- Name=Parse_String();
- Read_Targa_Image(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (PNG_TOKEN)
- Image->File_Type = PNG_FILE;
- Name=Parse_String();
- Read_Png_Image(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (PGM_TOKEN)
- Image->File_Type = PGM_FILE;
- Name=Parse_String();
- Read_PGM_Image(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- CASE (PPM_TOKEN)
- Image->File_Type = PPM_FILE;
- Name=Parse_String();
- Read_PPM_Image(Image, Name);
- POV_FREE(Name);
- EXIT
- END_CASE
-
- OTHERWISE
- Parse_Error_Str ("map file spec");
- END_CASE
- END_EXPECT
-
- if (!(Image->File_Type & Legal))
- Error ("File type not supported here.");
- return (Image);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static void Parse_Image_Map (Pigment)
- PIGMENT *Pigment;
- {
- int reg;
- IMAGE *Image;
-
- Parse_Begin();
-
- Image = Parse_Image (IMAGE_FILE);
- Image->Use_Colour_Flag = TRUE;
-
- EXPECT /* Look for image_attribs */
- CASE (ONCE_TOKEN)
- Image->Once_Flag=TRUE;
- END_CASE
-
- CASE (INTERPOLATE_TOKEN)
- Image->Interpolation_Type = (int)Parse_Float();
- END_CASE
-
- CASE (MAP_TYPE_TOKEN)
- Image->Map_Type = (int) Parse_Float ();
- END_CASE
-
- CASE (USE_COLOUR_TOKEN)
- Image->Use_Colour_Flag = TRUE;
- END_CASE
-
- CASE (USE_INDEX_TOKEN)
- Image->Use_Colour_Flag = FALSE;
- END_CASE
-
- CASE (ALPHA_TOKEN)
- Warn(1.55, "Keyword ALPHA discontinued. Use FILTER instead.");
-
- CASE (COLOUR_KEY_TOKEN)
- switch(Token.Function_Id)
- {
- case FILTER_TOKEN:
- EXPECT
- CASE (ALL_TOKEN)
- {
- DBL filter;
- filter = Parse_Float();
- for (reg = 0 ; reg < Image->Colour_Map_Size ; reg++)
- Image->Colour_Map[reg].Filter
- = (unsigned short) (filter *255.0);
- }
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- reg = (int)(Parse_Float() + 0.01);
- if (Image->Colour_Map == NULL)
- Not_With ("filter","non color-mapped image");
- if ((reg < 0) || (reg >= Image->Colour_Map_Size))
- Error ("FILTER color register value out of range.");
-
- Parse_Comma();
- Image->Colour_Map[reg].Filter
- = (unsigned short) (255.0 * Parse_Float());
- EXIT
- END_CASE
-
- END_EXPECT
- Pigment->Flags |= HAS_FILTER;
- break;
-
- case TRANSMIT_TOKEN:
- EXPECT
- CASE (ALL_TOKEN)
- {
- DBL transmit;
- transmit = Parse_Float();
- for (reg = 0 ; reg < Image->Colour_Map_Size ; reg++)
- Image->Colour_Map[reg].Transmit
- = (unsigned short) (transmit *255.0);
- }
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- reg = (int)(Parse_Float() + 0.01);
- if (Image->Colour_Map == NULL)
- Not_With ("transmit","non color-mapped image");
- if ((reg < 0) || (reg >= Image->Colour_Map_Size))
- Error ("TRANSMIT color register value out of range.");
-
- Parse_Comma();
- Image->Colour_Map[reg].Transmit
- = (unsigned short) (255.0 * Parse_Float());
- EXIT
- END_CASE
-
- END_EXPECT
- Pigment->Flags |= HAS_FILTER;
- break;
-
- default:
- UNGET
- Parse_Error_Str ("filter or transmit");
- break;
- }
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Pigment->Vals.Image=Image;
- Parse_End();
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static void Parse_Bump_Map (Tnormal)
- TNORMAL *Tnormal;
- {
- IMAGE *Image;
-
- Parse_Begin();
-
- Image = Parse_Image(IMAGE_FILE);
- Image->Use_Colour_Flag = TRUE;
-
- EXPECT
- CASE (ONCE_TOKEN)
- Image->Once_Flag=TRUE;
- END_CASE
-
- CASE (MAP_TYPE_TOKEN)
- Image->Map_Type = (int) Parse_Float ();
- END_CASE
-
- CASE (INTERPOLATE_TOKEN)
- Image->Interpolation_Type = (int)Parse_Float();
- END_CASE
-
- CASE (BUMP_SIZE_TOKEN)
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (USE_COLOUR_TOKEN)
- Image->Use_Colour_Flag = TRUE;
- END_CASE
-
- CASE (USE_INDEX_TOKEN)
- Image->Use_Colour_Flag = FALSE;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Tnormal->Vals.Image=Image;
-
- Parse_End();
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- void Parse_Pigment (Pigment_Ptr)
- PIGMENT **Pigment_Ptr;
- {
- EXPECT /* Look for [pigment_id] */
- CASE (PIGMENT_ID_TOKEN)
- Destroy_Pigment(*Pigment_Ptr);
- *Pigment_Ptr = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT /* End pigment_id */
-
- Parse_Pattern((TPATTERN *)(*Pigment_Ptr),PIGMENT_TYPE);
-
- if (Not_In_Default && ((*Pigment_Ptr)->Type == NO_PATTERN))
- {
- Warn(1.7, "Pigment type unspecified or not 1st item.");
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static void Parse_Pattern (New, TPat_Type)
- TPATTERN *New;
- int TPat_Type;
- {
- VECTOR Local_Vector;
- COLOUR Local_Colour;
- MATRIX Local_Matrix;
- TRANSFORM Local_Trans;
- TURB *Local_Turb;
- unsigned short Old_Type=New->Type;
- IMAGE *Old_Image = NULL;
-
- if (Old_Type==BITMAP_PATTERN)
- {
- Old_Image=New->Vals.Image;
- }
-
- EXPECT
- CASE (AGATE_TOKEN)
- New->Type = AGATE_PATTERN;
- Check_Turb(&(New->Warps));
- New->Vals.Agate_Turb_Scale = 1.0;
- EXIT
- END_CASE
-
- CASE (BOZO_TOKEN)
- New->Type = BOZO_PATTERN;
- EXIT
- END_CASE
-
- CASE (GRANITE_TOKEN)
- New->Type = GRANITE_PATTERN;
- EXIT
- END_CASE
-
- CASE (LEOPARD_TOKEN)
- New->Type = LEOPARD_PATTERN;
- EXIT
- END_CASE
-
- CASE (MARBLE_TOKEN)
- New->Type = MARBLE_PATTERN;
- New->Wave_Type = TRIANGLE_WAVE;
- EXIT
- END_CASE
-
- CASE (MANDEL_TOKEN)
- New->Type = MANDEL_PATTERN;
- New->Vals.Iterations = (int)Parse_Float();
- EXIT
- END_CASE
-
- CASE (ONION_TOKEN)
- New->Type = ONION_PATTERN;
- EXIT
- END_CASE
-
- CASE (PATTERN1_TOKEN)
- New->Type = PATTERN1_PATTERN;
- EXIT
- END_CASE
-
- CASE (PATTERN2_TOKEN)
- New->Type = PATTERN2_PATTERN;
- EXIT
- END_CASE
-
- CASE (PATTERN3_TOKEN)
- New->Type = PATTERN3_PATTERN;
- EXIT
- END_CASE
-
- CASE (BUMPY1_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- {
- Only_In("bumpy1","normal");
- }
- New->Type = BUMPY1_PATTERN;
- EXIT
- END_CASE
-
- CASE (BUMPY2_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- {
- Only_In("bumpy2","normal");
- }
- New->Type = BUMPY2_PATTERN;
- EXIT
- END_CASE
-
- CASE (BUMPY3_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- {
- Only_In("bumpy3","normal");
- }
- New->Type = BUMPY3_PATTERN;
- EXIT
- END_CASE
-
- CASE (SPIRAL1_TOKEN)
- New->Type = SPIRAL1_PATTERN;
- New->Vals.Arms = (short)Parse_Float ();
- New->Wave_Type = TRIANGLE_WAVE;
- EXIT
- END_CASE
-
- CASE (SPIRAL2_TOKEN)
- New->Type = SPIRAL2_PATTERN;
- New->Vals.Arms = (short)Parse_Float ();
- New->Wave_Type = TRIANGLE_WAVE;
- EXIT
- END_CASE
-
- CASE (SPOTTED_TOKEN)
- New->Type = SPOTTED_PATTERN;
- EXIT
- END_CASE
-
- CASE (WOOD_TOKEN)
- New->Type = WOOD_PATTERN;
- New->Wave_Type = TRIANGLE_WAVE;
- EXIT
- END_CASE
-
- CASE (GRADIENT_TOKEN)
- New->Type = GRADIENT_PATTERN;
- Parse_Vector (New->Vals.Gradient);
- EXIT
- END_CASE
-
- CASE (RADIAL_TOKEN)
- New->Type = RADIAL_PATTERN;
- EXIT
- END_CASE
-
- CASE (CRACKLE_TOKEN)
- New->Type = CRACKLE_PATTERN;
- EXIT
- END_CASE
-
- CASE_COLOUR
- if (TPat_Type != PIGMENT_TYPE)
- {
- Only_In("color","pigment");
- }
- New->Type = PLAIN_PATTERN;
- Parse_Colour (((PIGMENT *)New)->Colour);
- EXIT
- END_CASE
-
- CASE (CHECKER_TOKEN)
- New->Type = CHECKER_PATTERN;
- New->Frequency = 0.0;
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_List(2,&Check_Default_Map,TPat_Type);
- EXIT
- END_CASE
-
- CASE (BRICK_TOKEN)
- if (New->Type!=BRICK_PATTERN)
- {
- Make_Vector(New->Vals.Brick.Size,8.0,3.0,4.5);
- New->Vals.Brick.Mortar=0.5-Small_Tolerance*2.0;
- New->Type = BRICK_PATTERN;
- }
- New->Frequency = 0.0;
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_List(2,&Brick_Default_Map,TPat_Type);
- EXIT
- END_CASE
-
- CASE (HEXAGON_TOKEN)
- New->Type = HEXAGON_PATTERN;
- New->Frequency = 0.0;
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_List(3,&Hex_Default_Map,TPat_Type);
- EXIT
- END_CASE
-
- CASE (IMAGE_MAP_TOKEN)
- if (TPat_Type != PIGMENT_TYPE)
- {
- Only_In("image_map","pigment");
- }
-
- if (Old_Type==BITMAP_PATTERN)
- {
- Destroy_Image(Old_Image);
- }
-
- New->Type = BITMAP_PATTERN;
- New->Frequency = 0.0;
- Parse_Image_Map ((PIGMENT *)New);
- EXIT
- END_CASE
-
- CASE (BUMP_MAP_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- {
- Only_In("bump_map","normal");
- }
-
- if (Old_Type==BITMAP_PATTERN)
- {
- Destroy_Image(Old_Image);
- }
-
- New->Type = BITMAP_PATTERN;
- New->Frequency = 0.0;
- Parse_Bump_Map ((TNORMAL *)New);
- EXIT
- END_CASE
-
- CASE (WAVES_TOKEN)
- New->Type = WAVES_PATTERN;
- EXIT
- END_CASE
-
- CASE (RIPPLES_TOKEN)
- New->Type = RIPPLES_PATTERN;
- EXIT
- END_CASE
-
- CASE (WRINKLES_TOKEN)
- New->Type = WRINKLES_PATTERN;
- EXIT
- END_CASE
-
- CASE (BUMPS_TOKEN)
- New->Type = BUMPS_PATTERN;
- EXIT
- END_CASE
-
- CASE (DENTS_TOKEN)
- New->Type = DENTS_PATTERN;
- EXIT
- END_CASE
-
- CASE (QUILTED_TOKEN)
- New->Type = QUILTED_PATTERN;
- New->Vals.Quilted.Control0 = 1.0;
- New->Vals.Quilted.Control1 = 1.0;
- New->Frequency = 0.0;
- EXIT
- END_CASE
-
- CASE (AVERAGE_TOKEN)
- New->Type = AVERAGE_PATTERN;
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT /* Concludes pattern_body */
-
- if ((Old_Type==BITMAP_PATTERN) && (New->Type!=BITMAP_PATTERN))
- {
- Destroy_Image(Old_Image);
- }
-
- if (TPat_Type == NORMAL_TYPE)
- {
- Parse_Comma();
- ((TNORMAL *)New)->Amount = Allow_Float (((TNORMAL *)New)->Amount );
- }
-
- EXPECT /* Look for pattern_modifier */
- CASE (TURBULENCE_TOKEN)
- Local_Turb=Check_Turb(&(New->Warps));
- Parse_Vector_Float(Local_Turb->Turbulence);
- END_CASE
-
- CASE (COLOUR_MAP_TOKEN)
- if (TPat_Type != PIGMENT_TYPE)
- {
- Only_In("color_map","pigment");
- }
- if (New->Type == CHECKER_PATTERN ||
- New->Type == BRICK_PATTERN ||
- New->Type == HEXAGON_PATTERN ||
- New->Type == PLAIN_PATTERN ||
- New->Type == BITMAP_PATTERN)
- Warn(1.5, "Cannot use color map with this pigment type.");
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Colour_Map ();
- END_CASE
-
- CASE (PIGMENT_MAP_TOKEN)
- if (TPat_Type != PIGMENT_TYPE)
- {
- Only_In("pigment_map","pigment");
- }
- if (New->Type == CHECKER_PATTERN ||
- New->Type == BRICK_PATTERN ||
- New->Type == HEXAGON_PATTERN ||
- New->Type == PLAIN_PATTERN ||
- New->Type == BITMAP_PATTERN)
- Not_With ("pigment_map","this pigment type");
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_Map (PIGMENT_TYPE,New->Type);
- END_CASE
-
- CASE (SLOPE_MAP_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- {
- Only_In("slope_map","normal");
- }
- if (New->Type == CHECKER_PATTERN ||
- New->Type == BRICK_PATTERN ||
- New->Type == HEXAGON_PATTERN ||
- New->Type == PLAIN_PATTERN ||
- New->Type == AVERAGE_PATTERN ||
- New->Type == BITMAP_PATTERN)
- Not_With ("slope_map","this normal type");
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_Map (SLOPE_TYPE,New->Type);
- END_CASE
-
- CASE (NORMAL_MAP_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- {
- Only_In("normal_map","normal");
- }
- if (New->Type == CHECKER_PATTERN ||
- New->Type == BRICK_PATTERN ||
- New->Type == HEXAGON_PATTERN ||
- New->Type == PLAIN_PATTERN ||
- New->Type == BITMAP_PATTERN)
- Not_With ("normal_map","this normal type");
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_Map (NORMAL_TYPE,New->Type);
- END_CASE
-
- CASE (TEXTURE_MAP_TOKEN)
- if (TPat_Type != TEXTURE_TYPE)
- {
- Only_In("texture_map","texture");
- }
- if (New->Type == CHECKER_PATTERN ||
- New->Type == BRICK_PATTERN ||
- New->Type == HEXAGON_PATTERN ||
- New->Type == PLAIN_PATTERN ||
- New->Type == BITMAP_PATTERN)
- Not_With ("texture_map","this pattern type");
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Blend_Map (TEXTURE_TYPE,New->Type);
- END_CASE
-
- CASE (QUICK_COLOUR_TOKEN)
- if (TPat_Type != PIGMENT_TYPE)
- {
- Only_In("quick_color","pigment");
- }
- Parse_Colour (Local_Colour);
- if (opts.Quality_Flags & Q_QUICKC)
- {
- New->Type = PLAIN_PATTERN;
- Assign_Colour(((PIGMENT *)New)->Colour,Local_Colour);
- }
- END_CASE
-
- CASE (CONTROL0_TOKEN)
- if (New->Type == QUILTED_PATTERN)
- {
- New->Vals.Quilted.Control0 = Parse_Float ();
- }
- else
- {
- Not_With ("control0","this normal");
- }
- END_CASE
-
- CASE (CONTROL1_TOKEN)
- if (New->Type == QUILTED_PATTERN)
- {
- New->Vals.Quilted.Control1 = Parse_Float ();
- }
- else
- {
- Not_With ("control1","this normal");
- }
- END_CASE
-
- CASE (OCTAVES_TOKEN)
- Local_Turb=Check_Turb(&(New->Warps));
- Local_Turb->Octaves = (int)Parse_Float();
- if(Local_Turb->Octaves < 1)
- Local_Turb->Octaves = 1;
- if(Local_Turb->Octaves > 10) /* Avoid DOMAIN errors */
- Local_Turb->Octaves = 10;
- END_CASE
-
- CASE (OMEGA_TOKEN)
- Local_Turb=Check_Turb(&(New->Warps));
- Local_Turb->Omega = Parse_Float();
- END_CASE
-
- CASE (LAMBDA_TOKEN)
- Local_Turb=Check_Turb(&(New->Warps));
- Local_Turb->Lambda = Parse_Float();
- END_CASE
-
- CASE (FREQUENCY_TOKEN)
- New->Frequency = Parse_Float();
- END_CASE
-
- CASE (RAMP_WAVE_TOKEN)
- New->Wave_Type = RAMP_WAVE;
- END_CASE
-
- CASE (TRIANGLE_WAVE_TOKEN)
- New->Wave_Type = TRIANGLE_WAVE;
- END_CASE
-
- CASE (SINE_WAVE_TOKEN)
- New->Wave_Type = SINE_WAVE;
- END_CASE
-
- CASE (SCALLOP_WAVE_TOKEN)
- New->Wave_Type = SCALLOP_WAVE;
- END_CASE
-
- CASE (PHASE_TOKEN)
- New->Phase = Parse_Float();
- END_CASE
-
- CASE (BUMP_SIZE_TOKEN)
- if (TPat_Type != NORMAL_TYPE)
- Only_In ("bump_size","normal");
- ((TNORMAL *)New)->Amount = Parse_Float ();
- END_CASE
-
- CASE (AGATE_TURB_TOKEN)
- if (New->Type != AGATE_PATTERN)
- Not_With ("agate_turb","non-agate");
- New->Vals.Agate_Turb_Scale = Parse_Float();
- Check_Turb(&(New->Warps)); /* agate needs Octaves, Lambda etc. */
- END_CASE
-
- CASE (BRICK_SIZE_TOKEN)
- if (New->Type != BRICK_PATTERN)
- Not_With ("brick_size","non-brick");
- Parse_Vector(New->Vals.Brick.Size);
- END_CASE
-
- CASE (MORTAR_TOKEN)
- if (New->Type != BRICK_PATTERN)
- Not_With ("mortar","non-brick");
- New->Vals.Brick.Mortar = Parse_Float()-Small_Tolerance*2.0;
- END_CASE
-
- CASE (WARP_TOKEN)
- Parse_Warp(&(New->Warps));
- END_CASE
-
- CASE (TRANSLATE_TOKEN)
- Parse_Vector (Local_Vector);
- Translate_Tpattern (New, Local_Vector);
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector (Local_Vector);
- Rotate_Tpattern (New, Local_Vector);
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Scale_Vector (Local_Vector);
- Scale_Tpattern (New, Local_Vector);
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Local_Matrix);
- Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
- Transform_Tpattern (New, &Local_Trans);
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- Transform_Tpattern (New, (TRANSFORM *)Token.Constant_Data);
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- if ((TPat_Type==TEXTURE_TYPE) && (New->Type!=PLAIN_PATTERN) &&
- (New->Blend_Map==NULL))
- {
- Error("Patterned texture must have texture_map.");
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- void Parse_Tnormal (Tnormal_Ptr)
- TNORMAL **Tnormal_Ptr;
- {
- EXPECT /* Look for [tnormal_id] */
- CASE (TNORMAL_ID_TOKEN)
- Destroy_Tnormal(*Tnormal_Ptr);
- *Tnormal_Ptr = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT /* End [tnormal_id] */
-
- if (*Tnormal_Ptr == NULL)
- if ((Default_Texture->Tnormal) != NULL)
- *Tnormal_Ptr = Copy_Tnormal ((Default_Texture->Tnormal));
- else
- *Tnormal_Ptr = Create_Tnormal ();
-
- Parse_Pattern((TPATTERN *)*Tnormal_Ptr,NORMAL_TYPE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- void Parse_Finish (Finish_Ptr)
- FINISH **Finish_Ptr;
- {
- COLOUR Temp_Colour;
- FINISH *New;
- VECTOR Local_Vector;
-
- Parse_Begin ();
-
- EXPECT /* Look for zero or one finish_id */
- CASE (FINISH_ID_TOKEN)
- Destroy_Finish(*Finish_Ptr);
- *Finish_Ptr = Copy_Finish ((FINISH *) Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT /* End finish_id */
-
- New = *Finish_Ptr;
-
- EXPECT /* Look for zero or more finish_body */
- CASE (AMBIENT_TOKEN)
- Parse_Colour(Temp_Colour);
- New->Ambient[RED] = Temp_Colour[RED];
- New->Ambient[GREEN] = Temp_Colour[GREEN];
- New->Ambient[BLUE] = Temp_Colour[BLUE];
- END_CASE
-
- CASE (BRILLIANCE_TOKEN)
- New->Brilliance = Parse_Float ();
- END_CASE
-
- CASE (DIFFUSE_TOKEN)
- New->Diffuse = Parse_Float ();
- END_CASE
-
- CASE (REFLECTION_TOKEN)
- Parse_Colour(Temp_Colour);
- New->Reflection[RED] = Temp_Colour[RED];
- New->Reflection[GREEN] = Temp_Colour[GREEN];
- New->Reflection[BLUE] = Temp_Colour[BLUE];
- END_CASE
-
- CASE (REFRACTION_TOKEN)
- New->Refraction = Parse_Float ();
- END_CASE
-
- CASE (IOR_TOKEN)
- New->Index_Of_Refraction = Parse_Float ();
- END_CASE
-
- CASE (PHONG_TOKEN)
- New->Phong = Parse_Float ();
- END_CASE
-
- CASE (PHONG_SIZE_TOKEN)
- New->Phong_Size = Parse_Float ();
- END_CASE
-
- CASE (SPECULAR_TOKEN)
- New->Specular = Parse_Float ();
- END_CASE
-
- CASE (ROUGHNESS_TOKEN)
- New->Roughness = Parse_Float ();
- if (New->Roughness != 0.0)
- New->Roughness = 1.0/New->Roughness; /* CEY 12/92 */
- else
- Warn(0.0, "Zero roughness used.");
- END_CASE
-
- CASE (METALLIC_TOKEN)
- New->Metallic = 1.0;
- EXPECT
- CASE_FLOAT
- New->Metallic = Parse_Float();
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- END_CASE
-
- CASE (CAUSTICS_TOKEN)
- New->Caustics = Parse_Float() * 45.0;
- END_CASE
-
- CASE (CRAND_TOKEN)
- New->Crand = Parse_Float();
- END_CASE
-
- CASE (IRID_TOKEN) /* DMF */
- Parse_Begin();
- New->Irid = Parse_Float();
-
- EXPECT
- CASE (THICKNESS_TOKEN) /* DMF */
- New->Irid_Film_Thickness = Parse_Float();
- END_CASE
-
- CASE (TURBULENCE_TOKEN) /* DMF */
- Parse_Vector_Float(Local_Vector);
- New->Irid_Turb = Local_Vector[X];
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- Parse_End();
- END_CASE
-
- CASE (FADE_DISTANCE_TOKEN)
- New->Fade_Distance = Parse_Float();
- END_CASE
-
- CASE (FADE_POWER_TOKEN)
- New->Fade_Power = Parse_Float();
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT /* End of finish_body */
-
- EXPECT /* Look for finish_mods */
-
- /* CASE none implemented
- END_CASE */
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT /* End of finish_mods */
-
- Parse_End ();
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Parse_Halo
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Zsolt Szalavari
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- * Aug 1995 : Added and modified. [DB]
- *
- ******************************************************************************/
-
- void Parse_Halo (Halo_Ptr)
- HALO **Halo_Ptr;
- {
- int add_new_halo, new_color_map, i;
- SNGL *w;
- VECTOR Local_Vector;
- MATRIX Local_Matrix;
- TRANSFORM Local_Trans;
- HALO *New, *Next_Halo;
-
- add_new_halo = TRUE;
-
- new_color_map = FALSE;
-
- Next_Halo = *Halo_Ptr;
-
- Parse_Begin();
-
- /* Look for [halo_id] */
-
- EXPECT
- CASE (HALO_ID_TOKEN)
- add_new_halo = FALSE;
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- if (add_new_halo)
- {
- if ((Default_Texture->Halo) != NULL)
- {
- New = Copy_Halo((Default_Texture->Halo));
- }
- else
- {
- New = Create_Halo();
- }
- }
- else
- {
- New = Copy_Halo((HALO *)Token.Constant_Data);
- }
-
- EXPECT
- /* Look for halo rendering type. */
-
- CASE (ATTENUATING_TOKEN)
- New->Rendering_Type = HALO_ATTENUATING;
- END_CASE
-
- CASE (EMITTING_TOKEN)
- New->Rendering_Type = HALO_EMITTING;
- END_CASE
-
- CASE (GLOWING_TOKEN)
- New->Rendering_Type = HALO_GLOWING;
- END_CASE
-
- CASE (DUST_TOKEN)
- New->Rendering_Type = HALO_DUST;
- END_CASE
-
- CASE (VOLUME_RENDERED_TOKEN)
- New->Rendering_Type = HALO_VOLUME_RENDERED;
- END_CASE
-
- CASE (VOL_WITH_LIGHT_TOKEN)
- New->Rendering_Type = HALO_VOL_REND_WITH_LIGHT;
- END_CASE
-
- /* Look for halo density function. */
-
- CASE (CONSTANT_TOKEN)
- New->Type = HALO_CONSTANT;
- END_CASE
-
- CASE (LINEAR_TOKEN)
- New->Type = HALO_LINEAR;
- END_CASE
-
- CASE (CUBIC_TOKEN)
- New->Type = HALO_CUBIC;
- END_CASE
-
- CASE (POLY_TOKEN)
- New->Type = HALO_POLY;
- END_CASE
-
- CASE (VOLUME_OBJECT_TOKEN)
- New->Type = HALO_VOLUME_OBJECT;
- END_CASE
-
- /* Look for halo mapping type. */
-
- CASE (PLANAR_MAPPING_TOKEN)
- New->Mapping_Type = HALO_PLANAR_MAP;
- END_CASE
-
- CASE (SPHERICAL_MAPPING_TOKEN)
- New->Mapping_Type = HALO_SPHERICAL_MAP;
- END_CASE
-
- CASE (CYLINDRICAL_MAPPING_TOKEN)
- New->Mapping_Type = HALO_CYLINDRICAL_MAP;
- END_CASE
-
- CASE (BOX_MAPPING_TOKEN)
- New->Mapping_Type = HALO_BOX_MAP;
- END_CASE
-
- /* Look for halo sampling stuff. */
-
- CASE (SAMPLES_TOKEN)
- New->Samples = Parse_Float();
- END_CASE
-
- CASE (AA_LEVEL_TOKEN)
- if ((New->AA_Level = (int)Parse_Float()) < 0)
- {
- Error("Illegal anti-aliasing level value in halo.\n");
- }
- END_CASE
-
- CASE (AA_THRESHOLD_TOKEN)
- New->AA_Threshold = Parse_Float();
- END_CASE
-
- CASE (JITTER_TOKEN)
- New->Jitter = Parse_Float();
- END_CASE
-
- /* Look for other identifiers. */
-
- CASE (DUST_TYPE_TOKEN)
- New->Dust_Type = (char)Parse_Float();
- if ((New->Dust_Type < 1) || (New->Dust_Type > SCATTERING_TYPES))
- {
- Warn(0.0, "Unknown halo dust type.");
- }
- END_CASE
-
- CASE (MAX_VALUE_TOKEN)
- New->Max_Value = Parse_Float();
- END_CASE
-
- CASE (EXPONENT_TOKEN)
- New->Exponent = Parse_Float();
- END_CASE
-
- CASE (ECCENTRICITY_TOKEN)
- New->Eccentricity = Parse_Float();
- END_CASE
-
- CASE (COLOUR_MAP_TOKEN)
- Destroy_Blend_Map(New->Blend_Map);
- New->Blend_Map = Parse_Colour_Map();
- new_color_map = TRUE;
- END_CASE
-
- CASE (TRANSLATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Translation_Transform(&Local_Trans, Local_Vector);
- Translate_One_Halo (New, &Local_Trans);
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Rotation_Transform(&Local_Trans, Local_Vector);
- Rotate_One_Halo (New, &Local_Trans);
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Scale_Vector (Local_Vector);
- Compute_Scaling_Transform(&Local_Trans, Local_Vector);
- Scale_One_Halo (New, &Local_Trans);
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Local_Matrix);
- Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
- Transform_One_Halo (New, &Local_Trans);
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- Transform_One_Halo (New, (TRANSFORM *)Token.Constant_Data);
- END_CASE
-
- CASE (TURBULENCE_TOKEN)
- if (New->Turb == NULL)
- {
- New->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- Parse_Vector_Float(New->Turb->Turbulence);
- END_CASE
-
- CASE (OCTAVES_TOKEN)
- if (New->Turb == NULL)
- {
- New->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- New->Turb->Octaves = (int)Parse_Float();
- if(New->Turb->Octaves < 1)
- New->Turb->Octaves = 1;
- if(New->Turb->Octaves > 10)
- New->Turb->Octaves = 10;
- END_CASE
-
- CASE (OMEGA_TOKEN)
- if (New->Turb == NULL)
- {
- New->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- New->Turb->Omega = Parse_Float();
- END_CASE
-
- CASE (LAMBDA_TOKEN)
- if (New->Turb == NULL)
- {
- New->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- New->Turb->Lambda = Parse_Float();
- END_CASE
-
- CASE (FREQUENCY_TOKEN)
- New->Frequency = Parse_Float();
- END_CASE
-
- CASE (PHASE_TOKEN)
- New->Phase = Parse_Float();
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- if (Not_In_Default && (New->Type == HALO_NO_HALO))
- {
- Warn(3.0, "Halo type unspecified.");
- }
-
- Parse_End();
-
- if (New->Blend_Map == NULL)
- {
- Error("No color map specified with halo.\n");
- }
- else
- {
- if (new_color_map)
- {
- /* Convert differential translucencies to differential opacities. */
-
- for (i = 0; i < New->Blend_Map->Number_Of_Entries; i++)
- {
- w = &(New->Blend_Map->Blend_Map_Entries[i].Vals.Colour[TRANSM]);
-
- *w = 1.0 - *w;
- }
- }
- }
-
- /* Link halo to exisiting halos. */
-
- /*
- if (add_new_halo)
- */
- {
- New->Next_Halo = Next_Halo;
- }
-
- *Halo_Ptr = New;
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- TEXTURE *Parse_Texture ()
- {
- VECTOR Local_Vector;
- MATRIX Local_Matrix;
- TRANSFORM Local_Trans;
- TEXTURE *Texture;
- int Modified_Pnf;
-
- if (opts.Language_Version < 3.0)
- {
- return(Parse_Vers1_Texture());
- }
-
- Modified_Pnf = FALSE;
-
- EXPECT /* First allow a texture identifier */
- CASE (TEXTURE_ID_TOKEN)
- Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
- Modified_Pnf = TRUE;
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- Texture = Copy_Textures (Default_Texture);
- EXIT
- END_CASE
- END_EXPECT
-
- /* If the texture identifer or the default texture was a PLAIN_PATTERN
- then allow its pigment, normal or finish to be overridden by
- pigment identifier, normal identifier and finish identifiers.
- This is a consession to backwards compatibility so that
- "texture{PIGMENT_IDENTIFIER}" etc. is legal even though it should
- be "texture{pigment{PIGMENT_IDENTIFIER}}"
- */
-
- /* Look for [pnf_texture] */
- if (Texture->Type == PLAIN_PATTERN)
- {
- EXPECT /* Look for [pnf_ids] */
- CASE (PIGMENT_ID_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Destroy_Pigment(Texture->Pigment);
- Texture->Pigment = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (TNORMAL_ID_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- Destroy_Tnormal(Texture->Tnormal);
- Texture->Tnormal = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (FINISH_ID_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Destroy_Finish(Texture->Finish);
- Texture->Finish = Copy_Finish ((FINISH *) Token.Constant_Data);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (HALO_ID_TOKEN)
- Warn_State(Token.Token_Id, HALO_TOKEN);
- Destroy_Halo(Texture->Halo);
- Texture->Halo = Copy_Halo ((HALO *) Token.Constant_Data);
- Modified_Pnf = TRUE;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- /* If the texture identifer or the default texture was a PLAIN_PATTERN
- then allow its pigment, normal or finish to be overridden by
- pigment, normal or finish statement. Also allow transformations.
- */
-
- EXPECT /* Modify previous pnf */
- CASE (PIGMENT_TOKEN)
- Parse_Begin ();
- Parse_Pigment ( &(Texture->Pigment) );
- Parse_End ();
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (TNORMAL_TOKEN)
- Parse_Begin ();
- Parse_Tnormal ( &(Texture->Tnormal) );
- Parse_End ();
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (FINISH_TOKEN)
- Parse_Finish ( &(Texture->Finish) );
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (HALO_TOKEN)
- Parse_Halo(&(Texture->Halo));
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (TRANSLATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Translation_Transform(&Local_Trans, Local_Vector);
- Translate_Textures (Texture, &Local_Trans);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Rotation_Transform(&Local_Trans, Local_Vector);
- Rotate_Textures (Texture, &Local_Trans);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Scale_Vector (Local_Vector);
- Compute_Scaling_Transform(&Local_Trans, Local_Vector);
- Scale_Textures (Texture, &Local_Trans);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Local_Matrix);
- Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
- Transform_Textures (Texture, &Local_Trans);
- Modified_Pnf = TRUE;
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
- Modified_Pnf = TRUE;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- }
- else
- {
- /* Here it is not a PLAIN_PATTERN texture and since default textures
- must be plain then this was a texture identifier that was a special
- texture. Allow transforms. The "if(!Modified_Pnf)..." below
- will always fail if we came here. So we return after the
- transforms. */
- Parse_Texture_Transform(Texture);
- }
-
- /* If we've modified the default texture with a p,n, or f then this
- has to stay a PLAIN_PATTERN pnf texture. We won't allow
- a texture_map or pattern. Therefore quit now.
- */
-
- if (!Modified_Pnf)
- {
- /* At this point we've either got a texture statement that had
- no p, n or f. Nor any texture identifier. Basically it means
- this is a patterned texture_map texture. */
-
- EXPECT
- CASE (TILES_TOKEN)
- Destroy_Textures (Texture);
- Texture = Parse_Tiles();
- Parse_Texture_Transform(Texture);
- EXIT
- END_CASE
-
- CASE (MATERIAL_MAP_TOKEN)
- Destroy_Textures (Texture);
- Texture = Parse_Material_Map ();
- Parse_Texture_Transform(Texture);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET;
- Destroy_Pigment(Texture->Pigment);
- Destroy_Tnormal(Texture->Tnormal);
- Destroy_Finish(Texture->Finish);
- Destroy_Halo(Texture->Halo);
- Texture->Pigment = NULL;
- Texture->Tnormal = NULL;
- Texture->Finish = NULL;
- Texture->Halo = NULL;
- Parse_Pattern((TPATTERN *)Texture,TEXTURE_TYPE);
- EXIT
- END_CASE
- END_EXPECT
- }
-
- return (Texture);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static TEXTURE *Parse_Tiles()
- {
- TEXTURE *Texture, *Local_Texture;
- BLEND_MAP_ENTRY *Entry;
-
- Parse_Begin ();
-
- Texture = Create_Texture ();
- Destroy_Pigment(Texture->Pigment);
- Destroy_Tnormal(Texture->Tnormal);
- Destroy_Finish(Texture->Finish);
- Destroy_Halo(Texture->Halo);
- Texture->Pigment = NULL;
- Texture->Tnormal = NULL;
- Texture->Finish = NULL;
- Texture->Halo = NULL;
- Texture->Type = CHECKER_PATTERN;
-
- Texture->Blend_Map = Create_Blend_Map();
- Texture->Blend_Map->Number_Of_Entries = 2;
- Texture->Blend_Map->Blend_Map_Entries = Entry = Create_BMap_Entries (2);
- Texture->Blend_Map->Type = TEXTURE_TYPE;
- Entry[0].Vals.Texture=NULL;
- Entry[0].value=0.0;
- Entry[0].Same=FALSE;
- Entry[1].Vals.Texture=NULL;
- Entry[1].value=1.0;
- Entry[1].Same=FALSE;
-
- /* Note first tile is 1, 2nd tile is 0 to keep compatible with old tiles */
-
- EXPECT
- CASE (TEXTURE_TOKEN)
- Parse_Begin ();
- Local_Texture = Parse_Texture ();
- Link_Textures(&(Entry[1].Vals.Texture),Local_Texture);
- Parse_End ();
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- GET (TILE2_TOKEN);
-
- EXPECT
- CASE (TEXTURE_TOKEN)
- Parse_Begin ();
- Local_Texture = Parse_Texture ();
- Link_Textures(&(Entry[0].Vals.Texture),Local_Texture);
- Parse_End ();
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Parse_End ();
-
- return (Texture);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static TEXTURE *Parse_Material_Map()
- {
- TEXTURE *Texture, *Local_Texture;
- Parse_Begin ();
-
- Texture = Create_Texture ();
- Destroy_Pigment(Texture->Pigment);
- Destroy_Tnormal(Texture->Tnormal);
- Destroy_Finish(Texture->Finish);
- Destroy_Halo(Texture->Halo);
- Texture->Pigment = NULL;
- Texture->Tnormal = NULL;
- Texture->Finish = NULL;
- Texture->Halo = NULL;
- Texture->Type = BITMAP_PATTERN;
-
- Texture->Vals.Image = Parse_Image(MATERIAL_FILE);
- Texture->Vals.Image->Use_Colour_Flag = FALSE;
-
- EXPECT
- CASE (ONCE_TOKEN)
- Texture->Vals.Image->Once_Flag=TRUE;
- END_CASE
-
- CASE (INTERPOLATE_TOKEN)
- Texture->Vals.Image->Interpolation_Type=(int)Parse_Float();
- END_CASE
-
- CASE (MAP_TYPE_TOKEN)
- Texture->Vals.Image->Map_Type = (int) Parse_Float ();
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- GET (TEXTURE_TOKEN) /* First material */
- Parse_Begin();
- Texture->Materials = Local_Texture = Parse_Texture ();
- Parse_End();
- Texture->Num_Of_Mats++;
-
- EXPECT /* Subsequent materials */
- CASE (TEXTURE_TOKEN)
- Parse_Begin();
- Local_Texture->Next_Material = Parse_Texture ();
- Parse_End();
- Local_Texture = Local_Texture->Next_Material;
- Texture->Num_Of_Mats++;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Parse_End ();
-
- return(Texture);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static TEXTURE *Parse_Vers1_Texture ()
- {
- VECTOR Local_Vector;
- COLOUR Local_Colour;
- MATRIX Local_Matrix;
- TRANSFORM Local_Trans;
- TURB *Local_Turb;
- TEXTURE *Texture;
- PIGMENT *Pigment;
- TNORMAL *Tnormal;
- FINISH *Finish;
-
- EXPECT /* Look for texture_body */
- CASE (TILES_TOKEN)
- Texture = Parse_Tiles();
- EXIT
- END_CASE
-
- CASE (MATERIAL_MAP_TOKEN)
- Texture = Parse_Material_Map ();
- EXIT
- END_CASE
-
- CASE (TEXTURE_ID_TOKEN)
- Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- Texture = Copy_Textures (Default_Texture);
- EXIT
- END_CASE
- END_EXPECT
-
- /* Look for [pnf_texture] */
- if (Texture->Type == PLAIN_PATTERN)
- {
- EXPECT /* Look for [pnf_ids] */
- CASE (PIGMENT_ID_TOKEN)
- Destroy_Pigment(Texture->Pigment);
- Texture->Pigment = Copy_Pigment ((PIGMENT *) Token.Constant_Data);
- END_CASE
-
- CASE (TNORMAL_ID_TOKEN)
- Destroy_Tnormal(Texture->Tnormal);
- Texture->Tnormal = Copy_Tnormal ((TNORMAL *) Token.Constant_Data);
- END_CASE
-
- CASE (FINISH_ID_TOKEN)
- Destroy_Finish(Texture->Finish);
- Texture->Finish = Copy_Finish ((FINISH *) Token.Constant_Data);
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Pigment = Texture->Pigment;
- Tnormal = Texture->Tnormal;
- Finish = Texture->Finish;
- /* Halo = Texture->Halo;*/
-
- EXPECT
- CASE (PIGMENT_TOKEN)
- Parse_Begin ();
- Parse_Pigment ( &(Texture->Pigment) );
- Parse_End ();
- END_CASE
-
- CASE (TNORMAL_TOKEN)
- Parse_Begin ();
- Parse_Tnormal ( &(Texture->Tnormal) );
- Parse_End ();
- END_CASE
-
- CASE (FINISH_TOKEN)
- Parse_Finish ( &(Texture->Finish) );
- END_CASE
-
- /***********************************************************************
- PIGMENT STUFF OUTSIDE PIGMENT{}
- NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
- ***********************************************************************/
- CASE (AGATE_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = AGATE_PATTERN;
- Pigment->Vals.Agate_Turb_Scale = 1.0;
- Check_Turb(&(Pigment->Warps)); /* agate needs Octaves, Lambda etc. */
- END_CASE
-
- CASE (BOZO_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = BOZO_PATTERN;
- END_CASE
-
- CASE (GRANITE_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = GRANITE_PATTERN;
- END_CASE
-
- CASE (LEOPARD_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = LEOPARD_PATTERN;
- END_CASE
-
- CASE (MARBLE_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = MARBLE_PATTERN;
- END_CASE
-
- CASE (MANDEL_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = MANDEL_PATTERN;
- Pigment->Vals.Iterations = (int)Parse_Float();
- END_CASE
-
- CASE (ONION_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = ONION_PATTERN;
- END_CASE
-
- CASE (PATTERN1_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = PATTERN1_PATTERN;
- END_CASE
-
- CASE (PATTERN2_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = PATTERN2_PATTERN;
- END_CASE
-
- CASE (PATTERN3_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = PATTERN3_PATTERN;
- END_CASE
-
- CASE (SPOTTED_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = SPOTTED_PATTERN;
- END_CASE
-
- CASE (WOOD_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = WOOD_PATTERN;
- END_CASE
-
- CASE (GRADIENT_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = GRADIENT_PATTERN;
- Parse_Vector (Pigment->Vals.Gradient);
- END_CASE
-
- CASE_COLOUR
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = PLAIN_PATTERN;
- Parse_Colour (Pigment->Colour);
- END_CASE
-
- CASE (CHECKER_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = CHECKER_PATTERN;
- Pigment->Frequency = 0.0;
- Destroy_Blend_Map(Pigment->Blend_Map);
- Pigment->Blend_Map = Parse_Blend_List(2,&Check_Default_Map,COLOUR_TYPE);
- END_CASE
-
- CASE (HEXAGON_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = HEXAGON_PATTERN;
- Pigment->Frequency = 0.0;
- Destroy_Blend_Map(Pigment->Blend_Map);
- Pigment->Blend_Map = Parse_Blend_List(3,&Hex_Default_Map,COLOUR_TYPE);
- END_CASE
-
- CASE (IMAGE_MAP_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Pigment->Type = BITMAP_PATTERN;
- Pigment->Frequency = 0.0;
- Parse_Image_Map (Pigment);
- END_CASE
-
- CASE (TURBULENCE_TOKEN)
- Local_Turb=Check_Turb(&(Pigment->Warps));
- Parse_Vector_Float(Local_Turb->Turbulence);
- END_CASE
-
- CASE (COLOUR_MAP_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- if (Pigment->Type == CHECKER_PATTERN ||
- Pigment->Type == HEXAGON_PATTERN ||
- Pigment->Type == PLAIN_PATTERN ||
- Pigment->Type == BITMAP_PATTERN)
- Warn(1.5, "Cannot use color map with this pigment type.");
- Destroy_Blend_Map(Pigment->Blend_Map);
- Pigment->Blend_Map = Parse_Colour_Map ();
- END_CASE
-
- CASE (QUICK_COLOUR_TOKEN)
- Warn_State(Token.Token_Id, PIGMENT_TOKEN);
- Parse_Colour (Local_Colour);
- if (opts.Quality_Flags & Q_QUICKC)
- {
- Assign_Colour(Pigment->Colour,Local_Colour);
- }
- END_CASE
-
- CASE (OCTAVES_TOKEN)
- Local_Turb=Check_Turb(&(Pigment->Warps));
- Local_Turb->Octaves = (int)Parse_Float();
- if(Local_Turb->Octaves < 1)
- Local_Turb->Octaves = 1;
- if(Local_Turb->Octaves > 10) /* Avoid DOMAIN errors */
- Local_Turb->Octaves = 10;
- END_CASE
-
- CASE (OMEGA_TOKEN)
- Local_Turb=Check_Turb(&(Pigment->Warps));
- Local_Turb->Omega = Parse_Float();
- END_CASE
-
- CASE (LAMBDA_TOKEN)
- Local_Turb=Check_Turb(&(Pigment->Warps));
- Local_Turb->Lambda = Parse_Float();
- END_CASE
-
- /***********************************************************************
- TNORMAL STUFF OUTSIDE NORMAL{}
- NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
- ***********************************************************************/
- CASE (BUMPS_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = BUMPS_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (BUMPY1_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = BUMPY1_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (BUMPY2_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = BUMPY2_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (BUMPY3_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = BUMPY3_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (DENTS_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = DENTS_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (RIPPLES_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = RIPPLES_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (WAVES_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = WAVES_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (WRINKLES_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = WRINKLES_PATTERN;
- Tnormal->Amount = Parse_Float ();
- END_CASE
-
- CASE (BUMP_MAP_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- Tnormal->Type = BITMAP_PATTERN;
- Tnormal->Frequency = 0.0;
- Parse_Bump_Map (Tnormal);
- END_CASE
-
- CASE (FREQUENCY_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- if (!(Tnormal->Type == RIPPLES_PATTERN || Tnormal->Type == WAVES_PATTERN))
- if (opts.Language_Version >= 1.5)
- Warn(1.5, "Cannot use frequency with this normal.");
- Tnormal->Frequency = Parse_Float();
- END_CASE
-
- CASE (PHASE_TOKEN)
- Warn_State(Token.Token_Id, TNORMAL_TOKEN);
- ADD_TNORMAL
- if (!(Tnormal->Type == RIPPLES_PATTERN || Tnormal->Type == WAVES_PATTERN))
- if (opts.Language_Version >= 1.5)
- Warn(1.5, "Cannot use phase with this normal.");
- Tnormal->Phase = Parse_Float();
- END_CASE
-
-
- /***********************************************************************
- FINISH STUFF OUTSIDE FINISH{}
- NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
- ***********************************************************************/
- CASE (AMBIENT_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Ambient[RED] =
- Finish->Ambient[GREEN] =
- Finish->Ambient[BLUE] = Parse_Float ();
- END_CASE
-
- CASE (BRILLIANCE_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Brilliance = Parse_Float ();
- END_CASE
-
- CASE (DIFFUSE_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Diffuse = Parse_Float ();
- END_CASE
-
- CASE (REFLECTION_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Reflection[RED] =
- Finish->Reflection[GREEN] =
- Finish->Reflection[BLUE] = Parse_Float ();
- END_CASE
-
- CASE (REFRACTION_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Refraction = Parse_Float ();
- END_CASE
-
- CASE (IOR_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Index_Of_Refraction = Parse_Float ();
- END_CASE
-
- CASE (PHONG_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Phong = Parse_Float ();
- END_CASE
-
- CASE (PHONG_SIZE_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Phong_Size = Parse_Float ();
- END_CASE
-
- CASE (SPECULAR_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Specular = Parse_Float ();
- END_CASE
-
- CASE (ROUGHNESS_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Roughness = Parse_Float ();
- if (Finish->Roughness != 0.0)
- Finish->Roughness = 1.0/Finish->Roughness; /* CEY 12/92 */
- else
- Warn(0.0, "Zero roughness used.");
- END_CASE
-
- CASE (METALLIC_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Metallic = 1.0;
- END_CASE
-
- CASE (CRAND_TOKEN)
- Warn_State(Token.Token_Id, FINISH_TOKEN);
- Finish->Crand = Parse_Float();
- END_CASE
-
- CASE_FLOAT
- Finish->Crand = Parse_Float();
- Warn(1.5, "Should use crand keyword in finish statement.");
- END_CASE
-
- CASE (TRANSLATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Translation_Transform(&Local_Trans, Local_Vector);
- Translate_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Rotation_Transform(&Local_Trans, Local_Vector);
- Rotate_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Scale_Vector (Local_Vector);
- Compute_Scaling_Transform(&Local_Trans, Local_Vector);
- Scale_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Local_Matrix);
- Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
- Transform_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
- END_CASE
-
- CASE (TEXTURE_ID_TOKEN)
- Warn(0.0, "Texture identifier overwriting previous values.");
- Destroy_Textures(Texture);
- Texture = Copy_Textures((TEXTURE *) Token.Constant_Data);
- Pigment = Texture->Pigment;
- Tnormal = Texture->Tnormal;
- Finish = Texture->Finish;
- /* Halo = Texture->Halo;*/
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- /***********************************************************************/
-
- END_EXPECT
-
- if (Not_In_Default && (Texture->Pigment->Type == NO_PATTERN) &&
- !(opts.Language_Version < 1.5))
- Parse_Error(PIGMENT_ID_TOKEN);
-
- }
-
- Parse_Texture_Transform(Texture);
-
- return (Texture);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static void Parse_Texture_Transform (Texture)
- TEXTURE *Texture;
- {
- VECTOR Local_Vector;
- MATRIX Local_Matrix;
- TRANSFORM Local_Trans;
-
- EXPECT
- CASE (TRANSLATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Translation_Transform(&Local_Trans, Local_Vector);
- Translate_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector (Local_Vector);
- Compute_Rotation_Transform(&Local_Trans, Local_Vector);
- Rotate_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Scale_Vector (Local_Vector);
- Compute_Scaling_Transform(&Local_Trans, Local_Vector);
- Scale_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Local_Matrix);
- Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
- Transform_Textures (Texture, &Local_Trans);
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- Transform_Textures (Texture, (TRANSFORM *)Token.Constant_Data);
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- }
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Parse_Atmosphere
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Nov 1994 : Creation.
- *
- ******************************************************************************/
-
- ATMOSPHERE *Parse_Atmosphere()
- {
- ATMOSPHERE *Atmosphere;
-
- Parse_Begin();
-
- EXPECT
- CASE(ATMOSPHERE_ID_TOKEN)
- Atmosphere = Copy_Atmosphere((ATMOSPHERE *)Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- Atmosphere = Create_Atmosphere();
- EXIT
- END_CASE
- END_EXPECT
-
- EXPECT
- CASE (TYPE_TOKEN)
- Atmosphere->Type = (int)Parse_Float();
- if ((Atmosphere->Type < 1) || (Atmosphere->Type > SCATTERING_TYPES))
- {
- Warn(0.0, "Unknown atmospheric scattering type.");
- }
- END_CASE
-
- CASE (DISTANCE_TOKEN)
- Atmosphere->Distance = Parse_Float();
- END_CASE
-
- CASE (SAMPLES_TOKEN)
- if ((Atmosphere->Samples = (int)Parse_Float()) < 1)
- {
- Error("Illegal samples value in atmosphere.\n");
- }
- END_CASE
-
- CASE (SCATTERING_TOKEN)
- Atmosphere->Scattering = Parse_Float();
- END_CASE
-
- CASE (AA_LEVEL_TOKEN)
- if ((Atmosphere->AA_Level = (int)Parse_Float()) < 0)
- {
- Error("Illegal level value in atmosphere.\n");
- }
- END_CASE
-
- CASE (AA_THRESHOLD_TOKEN)
- Atmosphere->AA_Threshold = Parse_Float();
- END_CASE
-
- CASE (JITTER_TOKEN)
- Atmosphere->Jitter = Parse_Float();
- END_CASE
-
- CASE (ECCENTRICITY_TOKEN)
- Atmosphere->Eccentricity = Parse_Float();
- END_CASE
-
- CASE_COLOUR
- Parse_Colour(Atmosphere->Colour);
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Parse_End();
-
- return(Atmosphere);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- FOG *Parse_Fog()
- {
- VECTOR Vector;
- MATRIX Matrix;
- TRANSFORM Trans;
- FOG *Fog;
-
- Parse_Begin();
-
- EXPECT
- CASE(FOG_ID_TOKEN)
- Fog = Copy_Fog ((FOG *) Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- Fog = Create_Fog();
- EXIT
- END_CASE
- END_EXPECT
-
- EXPECT
- CASE_COLOUR
- Parse_Colour(Fog->Colour);
- END_CASE
-
- CASE (DISTANCE_TOKEN)
- Fog->Distance = Parse_Float();
- END_CASE
-
- CASE_FLOAT
- Warn(1.5, "Should use distance keyword.");
- Fog->Distance = Parse_Float();
- END_CASE
-
- CASE (FOG_TYPE_TOKEN)
- Fog->Type = (int)Parse_Float();
- if ((Fog->Type < ORIG_FOG) || (Fog->Type > FOG_TYPES))
- {
- Warn(0.0, "Unknown fog type.");
- }
- END_CASE
-
- CASE (FOG_ALT_TOKEN)
- Fog->Alt = Parse_Float();
- END_CASE
-
- CASE (FOG_OFFSET_TOKEN)
- Fog->Offset = Parse_Float();
- END_CASE
-
- CASE (TURB_DEPTH_TOKEN)
- Fog->Turb_Depth = Parse_Float();
- END_CASE
-
- CASE (UP_TOKEN)
- Parse_Vector(Fog->Up);
- END_CASE
-
- CASE (TURBULENCE_TOKEN)
- if (Fog->Turb == NULL)
- {
- Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- Parse_Vector_Float(Fog->Turb->Turbulence);
- END_CASE
-
- CASE (OCTAVES_TOKEN)
- if (Fog->Turb == NULL)
- {
- Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- Fog->Turb->Octaves = (int)Parse_Float();
- if(Fog->Turb->Octaves < 1)
- Fog->Turb->Octaves = 1;
- if(Fog->Turb->Octaves > 10)
- Fog->Turb->Octaves = 10;
- END_CASE
-
- CASE (OMEGA_TOKEN)
- if (Fog->Turb == NULL)
- {
- Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- Fog->Turb->Omega = Parse_Float();
- END_CASE
-
- CASE (LAMBDA_TOKEN)
- if (Fog->Turb == NULL)
- {
- Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
- }
- Fog->Turb->Lambda = Parse_Float();
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector(Vector);
- Compute_Rotation_Transform(&Trans, Vector);
- MTransDirection(Fog->Up, Fog->Up, &Trans);
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Vector(Vector);
- Compute_Scaling_Transform(&Trans, Vector);
- MTransDirection(Fog->Up, Fog->Up, &Trans);
- END_CASE
-
- CASE (TRANSLATE_TOKEN)
- Parse_Vector(Vector);
- Warn(0.0, "A fog's up vector can't be translated.");
- /*
- Compute_Translation_Transform(&Trans, Vector);
- MTransDirection(Fog->Up, Fog->Up, &Trans);
- */
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Matrix);
- Compute_Matrix_Transform(&Trans, Matrix);
- MTransDirection(Fog->Up, Fog->Up, &Trans);
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- MTransDirection(Fog->Up, Fog->Up, (TRANSFORM *)Token.Constant_Data);
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Parse_End ();
-
- /* Make sure the up vector is normalized. */
-
- VNormalize(Fog->Up, Fog->Up);
-
- return(Fog);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Parse_Rainbow
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Jul 1994 : Creation.
- *
- * Dec 1994 : Modified to work with multiple rainbows. [DB]
- *
- * Apr 1995 : Added code for rainbow arcs. [DB]
- *
- ******************************************************************************/
-
- RAINBOW *Parse_Rainbow()
- {
- int Angle1, Angle2;
- DBL dot;
- RAINBOW *Rainbow;
-
- Angle1 = Angle2 = FALSE;
-
- Parse_Begin();
-
- EXPECT
- CASE(RAINBOW_ID_TOKEN)
- Rainbow = Copy_Rainbow ((RAINBOW *) Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- Rainbow = Create_Rainbow();
- EXIT
- END_CASE
- END_EXPECT
-
- EXPECT
- CASE (ANGLE_TOKEN)
- Rainbow->Angle = Parse_Float();
- END_CASE
-
- CASE (DIRECTION_TOKEN)
- Parse_Vector(Rainbow->Antisolar_Vector);
- END_CASE
-
- CASE (COLOUR_MAP_TOKEN)
- Rainbow->Pigment = Create_Pigment();
- Rainbow->Pigment->Blend_Map = Parse_Colour_Map();
- Rainbow->Pigment->Type = GRADIENT_PATTERN;
- Make_Vector (Rainbow->Pigment->Vals.Gradient,1.0,0.0,0.0);
- END_CASE
-
- CASE (DISTANCE_TOKEN)
- Rainbow->Distance = Parse_Float();
- END_CASE
-
- CASE (JITTER_TOKEN)
- Rainbow->Jitter = Parse_Float();
- END_CASE
-
- CASE (WIDTH_TOKEN)
- Rainbow->Width = Parse_Float();
- END_CASE
-
- CASE (UP_TOKEN)
- Parse_Vector(Rainbow->Up_Vector);
- END_CASE
-
- CASE (FALLOFF_ANGLE_TOKEN)
- Angle1 = TRUE;
- Rainbow->Falloff_Angle = Parse_Float();
- if ((Rainbow->Falloff_Angle < 0.0) || (Rainbow->Falloff_Angle > 360.0))
- {
- Error("Illegal falloff angle in rainbow (Use value from 0 to 360 degrees).\n");
- }
- Rainbow->Falloff_Angle *= M_PI / 360.0;
- END_CASE
-
- CASE (ARC_ANGLE_TOKEN)
- Angle2 = TRUE;
- Rainbow->Arc_Angle = Parse_Float();
- if ((Rainbow->Arc_Angle < 0.0) || (Rainbow->Arc_Angle > 360.0))
- {
- Error("Illegal arc angle in rainbow (Use value from 0 to 360 degrees).\n");
- }
- Rainbow->Arc_Angle *= M_PI / 360.0;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Parse_End();
-
- /* Setup falloff angle. */
-
- if (Angle2 && !Angle1)
- {
- Rainbow->Falloff_Angle = Rainbow->Arc_Angle;
- }
-
- /* Test if arc angle is greater or equal to falloff angle. */
-
- if (Rainbow->Arc_Angle < Rainbow->Falloff_Angle)
- {
- Error("Arc angle is smaller than falloff angle in rainbow.\n");
- }
-
- /* Get falloff region width.*/
-
- Rainbow->Falloff_Width = Rainbow->Arc_Angle - Rainbow->Falloff_Angle;
-
- /* Check for illegal vectors. */
-
- VDot(dot, Rainbow->Antisolar_Vector, Rainbow->Antisolar_Vector);
-
- if (fabs(dot) < EPSILON)
- {
- Error("Rainbow's direction vector is zero.\n");
- }
-
- VDot(dot, Rainbow->Up_Vector, Rainbow->Up_Vector);
-
- if (fabs(dot) < EPSILON)
- {
- Error("Rainbow's up vector is zero.\n");
- }
-
- VNormalizeEq(Rainbow->Antisolar_Vector);
- VNormalizeEq(Rainbow->Up_Vector);
-
- VDot(dot, Rainbow->Up_Vector, Rainbow->Antisolar_Vector);
-
- if (fabs(1.0 - fabs(dot)) < EPSILON)
- {
- Error("Rainbow's up and direction vector are co-linear.\n");
- }
-
- /* Make sure that up and antisolar vector are perpendicular. */
-
- VCross(Rainbow->Right_Vector, Rainbow->Up_Vector, Rainbow->Antisolar_Vector);
-
- VCross(Rainbow->Up_Vector, Rainbow->Antisolar_Vector, Rainbow->Right_Vector);
-
- VNormalizeEq(Rainbow->Up_Vector);
- VNormalizeEq(Rainbow->Right_Vector);
-
- /* Adjust rainbow angle and width. */
-
- Rainbow->Angle -= 0.5 * Rainbow->Width;
-
- Rainbow->Angle *= M_PI / 180.0;
- Rainbow->Width *= M_PI / 180.0;
-
- return(Rainbow);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Parse_Skysphere
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Jul 1994 : Creation.
- *
- * Dec 1994 : Modified to work with multiple skyspheres. [DB]
- *
- ******************************************************************************/
-
- SKYSPHERE *Parse_Skysphere()
- {
- VECTOR Local_Vector;
- MATRIX Local_Matrix;
- TRANSFORM Local_Trans;
- SKYSPHERE *Skysphere;
-
- Parse_Begin();
-
- EXPECT
- CASE(SKYSPHERE_ID_TOKEN)
- Skysphere = Copy_Skysphere((SKYSPHERE *)Token.Constant_Data);
- EXIT
- END_CASE
-
- OTHERWISE
- UNGET
- Skysphere = Create_Skysphere();
- EXIT
- END_CASE
- END_EXPECT
-
- EXPECT
- CASE (PIGMENT_TOKEN)
- Skysphere->Count++;
- Skysphere->Pigments = POV_REALLOC(Skysphere->Pigments, Skysphere->Count*sizeof(SKYSPHERE *), "sky-sphere pigment");
- Skysphere->Pigments[Skysphere->Count-1] = Create_Pigment();
- Parse_Begin();
- Parse_Pigment(&(Skysphere->Pigments[Skysphere->Count-1]));
- Parse_End();
- END_CASE
-
- CASE (TRANSLATE_TOKEN)
- Parse_Vector (Local_Vector);
- Translate_Skysphere(Skysphere, Local_Vector);
- END_CASE
-
- CASE (ROTATE_TOKEN)
- Parse_Vector (Local_Vector);
- Rotate_Skysphere(Skysphere, Local_Vector);
- END_CASE
-
- CASE (SCALE_TOKEN)
- Parse_Scale_Vector (Local_Vector);
- Scale_Skysphere(Skysphere, Local_Vector);
- END_CASE
-
- CASE (MATRIX_TOKEN)
- Parse_Matrix(Local_Matrix);
- Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
- Transform_Skysphere(Skysphere, &Local_Trans);
- END_CASE
-
- CASE (TRANSFORM_TOKEN)
- GET(TRANSFORM_ID_TOKEN)
- Transform_Skysphere(Skysphere, (TRANSFORM *)Token.Constant_Data);
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
-
- Parse_End();
-
- if (Skysphere->Count==0)
- {
- Error("Empty sky_sphere statement.");
- }
-
- return(Skysphere);
- }
-
- /*****************************************************************************
- *
- * FUNCTION : Check_BH_Parameters
- *
- * ARGUMENTS : bh - pointer to Black_Hole
- *
- * AUTHOR : CJC [7/95]
- *
- * DESCRIPTION : Applies sanity checks to the parameters of a black hole.
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static void Check_BH_Parameters (bh)
- BLACK_HOLE *bh;
- {
- if (bh->Repeat == FALSE) return ;
-
- if (bh->Repeat_Vector [X] > 0.0)
- {
- if (bh->Center [X] < bh->Radius)
- bh->Center [X] = bh->Radius ;
- if (bh->Repeat_Vector [X] < bh->Center [X] + bh->Radius + bh->Uncertainty_Vector [X])
- {
- bh->Repeat_Vector [X] = bh->Center [X] + bh->Radius + bh->Uncertainty_Vector [X] ;
- Warning (0.0, "Black Hole repeat vector X too small ; increased to %g\n", bh->Repeat_Vector [X]) ;
- }
- if (bh->Repeat_Vector [X] < Small_Tolerance)
- {
- Warning (0.0,"Black Hole repeat vector X is less than %f ; ignored\n", (float) Small_Tolerance) ;
- bh->Repeat_Vector [X] = 0.0 ;
- }
- }
-
- if (bh->Repeat_Vector [Y] > 0.0)
- {
- if (bh->Center [Y] < bh->Radius)
- bh->Center [Y] = bh->Radius ;
- if (bh->Repeat_Vector [Y] < bh->Center [Y] + bh->Radius + bh->Uncertainty_Vector [Y])
- {
- bh->Repeat_Vector [Y] = bh->Center [Y] + bh->Radius + bh->Uncertainty_Vector [Y] ;
- Warning (0.0, "Black Hole repeat vector Y too small ; increased to %g\n", bh->Repeat_Vector [Y]) ;
- }
- if (bh->Repeat_Vector [Y] < Small_Tolerance)
- {
- Warning (0.0, "Black Hole repeat vector Y is less than %f ; ignored\n", (float) Small_Tolerance) ;
- bh->Repeat_Vector [Y] = 0.0 ;
- }
- }
-
- if (bh->Repeat_Vector [Z] > 0.0)
- {
- if (bh->Center [Z] < bh->Radius)
- bh->Center [Z] = bh->Radius ;
- if (bh->Repeat_Vector [Z] < bh->Center [Z] + bh->Radius + bh->Uncertainty_Vector [Z])
- {
- bh->Repeat_Vector [Z] = bh->Center [Z] + bh->Radius + bh->Uncertainty_Vector [Z] ;
- Warning (0.0, "Black Hole repeat vector Z too small ; increased to %g\n", bh->Repeat_Vector [Z]) ;
- }
- if (bh->Repeat_Vector [Z] < Small_Tolerance)
- {
- Warning (0.0, "Black Hole repeat vector Z is less than %f ; ignored\n", (float) Small_Tolerance) ;
- bh->Repeat_Vector [Z] = 0.0 ;
- }
- }
- }
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Check_Turb
- *
- * INPUT
- *
- * Warps_Ptr : Address where the root warp of a warp list
- * is stored.
- *
- * OUTPUT
- *
- * Warps_Ptr : If *Warps_Ptr is NULL, a classic turb warp
- * is created and a pointer to it is stored
- *
- * RETURNS
- *
- * A pointer to the last warp in the chain which is guarenteed
- * to be a classic turb.
- *
- * AUTHOR
- *
- * CEY [2/95]
- *
- * DESCRIPTION : This routine is called when a classic outside-the-warp
- * turbulence parameter is parsed. One and only one classic turb may exist
- * in a warp chain. If there is one, it must be the last. This routine
- * traverses the warp chain and looks at the last link. If it is not a
- * classic turb then it adds one to the end and returns a pointer to it.
- * If the chain is empty, it creates a single link chain consisting of a
- * classic turb link. Future warp links get added ahead of the chain so
- * that any classic turb link is always last.
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static TURB *Check_Turb (Warps_Ptr)
- WARP **Warps_Ptr;
- {
- WARP *Temp=*Warps_Ptr;
-
- if (Temp == NULL)
- {
- *Warps_Ptr = Temp = Create_Warp(CLASSIC_TURB_WARP);
- }
- else
- {
- while (Temp->Next_Warp != NULL)
- {
- Temp=Temp->Next_Warp;
- }
-
- if (Temp->Warp_Type != CLASSIC_TURB_WARP)
- {
- Temp->Next_Warp=Create_Warp(CLASSIC_TURB_WARP);
- Temp=Temp->Next_Warp;
- }
- }
- return((TURB *)Temp);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * CHANGES
- *
- ******************************************************************************/
-
- static void Parse_Warp (Warp_Ptr)
- WARP **Warp_Ptr;
- {
- WARP *New = NULL;
- TURB *Turb;
- REPEAT *Repeat;
- BLACK_HOLE *Black_Hole;
- VECTOR Local_Vector;
-
- Parse_Begin();
-
- EXPECT
- CASE(TURBULENCE_TOKEN)
- New=Create_Warp(EXTRA_TURB_WARP);
- Turb=(TURB *)New;
- Parse_Vector(Turb->Turbulence);
- EXPECT
- CASE(OCTAVES_TOKEN)
- Turb->Octaves = (int)Parse_Float();
- if(Turb->Octaves < 1)
- Turb->Octaves = 1;
- if(Turb->Octaves > 10) /* Avoid DOMAIN errors */
- Turb->Octaves = 10;
- END_CASE
-
- CASE (OMEGA_TOKEN)
- Turb->Omega = Parse_Float();
- END_CASE
-
- CASE (LAMBDA_TOKEN)
- Turb->Lambda = Parse_Float();
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- EXIT
- END_CASE
-
- CASE(REPEAT_TOKEN)
- New=Create_Warp(REPEAT_WARP);
- Repeat=(REPEAT *)New;
- Parse_Vector(Local_Vector);
- Repeat->Axis=-1;
- if (Local_Vector[X]!=0.0)
- Repeat->Axis=X;
- if (Local_Vector[Y]!=0.0)
- if (Repeat->Axis < X)
- Repeat->Axis=Y;
- else
- Error("Can only repeat along 1 axis.");
- if (Local_Vector[Z]!=0.0)
- if (Repeat->Axis < X)
- Repeat->Axis=Z;
- else
- Error("Can only repeat along 1 axis.");
- if (Repeat->Axis < X)
- Error("No axis specified in repeat.");
- Repeat->Width=Local_Vector[Repeat->Axis];
-
- EXPECT
- CASE(OFFSET_TOKEN)
- Parse_Vector(Repeat->Offset);
- END_CASE
-
- CASE(FLIP_TOKEN)
- Parse_Vector(Repeat->Flip);
- if (Repeat->Flip[X]!=0.0) Repeat->Flip[X]=-1.0; else Repeat->Flip[X]=1.0;
- if (Repeat->Flip[Y]!=0.0) Repeat->Flip[Y]=-1.0; else Repeat->Flip[Y]=1.0;
- if (Repeat->Flip[Z]!=0.0) Repeat->Flip[Z]=-1.0; else Repeat->Flip[Z]=1.0;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- EXIT
- END_CASE
-
- CASE(BLACK_HOLE_TOKEN)
- New = Create_Warp(BLACK_HOLE_WARP) ;
- Black_Hole = (BLACK_HOLE *) New ;
- Parse_Vector (Local_Vector) ;
- Assign_Vector (Black_Hole->Center, Local_Vector) ;
- Parse_Comma () ;
- Black_Hole->Radius = Parse_Float () ;
- Black_Hole->Radius_Squared = Black_Hole->Radius * Black_Hole->Radius ;
- Black_Hole->Inverse_Radius = 1.0 / Black_Hole->Radius;
- Black_Hole->Strength = 1.0 ;
- Black_Hole->Power = 2.0 ;
- Black_Hole->Inverted = FALSE ;
- Black_Hole->Type = 0 ;
-
- EXPECT
- CASE(STRENGTH_TOKEN)
- Black_Hole->Strength = Parse_Float () ;
- END_CASE
-
- CASE(FALLOFF_TOKEN)
- Black_Hole->Power = Parse_Float () ;
- END_CASE
-
- CASE(INVERSE_TOKEN)
- Black_Hole->Inverted = TRUE ;
- END_CASE
-
- CASE(TYPE_TOKEN)
- Black_Hole->Type = (int) Parse_Float () ;
- END_CASE
-
- CASE(REPEAT_TOKEN)
- Parse_Vector (Black_Hole->Repeat_Vector) ;
- Black_Hole->Repeat = TRUE ;
- Check_BH_Parameters (Black_Hole) ;
- END_CASE
-
- CASE(TURBULENCE_TOKEN)
- Parse_Vector (Black_Hole->Uncertainty_Vector) ;
- Black_Hole->Uncertain = TRUE ;
- Check_BH_Parameters (Black_Hole) ;
- END_CASE
-
- OTHERWISE
- UNGET
- EXIT
- END_CASE
- END_EXPECT
- EXIT
- END_CASE
-
- CASE(SPIRAL_TOKEN)
- Error("Spiral warp not yet implemented.");
- END_CASE
-
- OTHERWISE
- Parse_Error_Str ("warp type");
- END_CASE
- END_EXPECT
-
- if (New==NULL)
- {
- Error("Empty warp statement.");
- }
-
- New->Next_Warp=*Warp_Ptr;
- *Warp_Ptr=New;
-
- Parse_End();
- }
-